import { NestFactory } from '@nestjs/core';
import { Logger, ValidationPipe } from '@nestjs/common';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { json, urlencoded } from 'express';
import { ConfigService } from '@nestjs/config';
import { ApiGatewayModule } from './api-gateway.module';
// @app
import { ValidationException, WinstonLogger } from '@app/common';
// logger
import { WinstonModule } from 'nest-winston';

async function bootstrap() {
  // create
  const app = await NestFactory.create(ApiGatewayModule, {
    logger: WinstonModule.createLogger({
      instance: WinstonLogger,
    }),
  });
  // config
  const configService = app.get(ConfigService);
  // enableCors
  app.enableCors({
    origin: (origin, callback) => {
      callback(null, origin || '*');
    },
    credentials: true, // 允许发送凭证（cookies、HTTP认证等）
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS', // 允许的方法
    allowedHeaders:
      'Authorization, Content-Type, Accept, Accept-Encoding, Accept-Language, Origin, User-Agent', // 允许的请求头
    optionsSuccessStatus: 204, // 预检请求成功状态码
  });
  app.use(json({ limit: '10mb' }));
  app.use(urlencoded({ extended: true, limit: '10mb' }));
  // 全局校验
  app.useGlobalPipes(
    new ValidationPipe({
      transform: true,
      whitelist: true,
      enableDebugMessages: true,
      stopAtFirstError: true,
      exceptionFactory: (errors) => {
        // 在这里实现自定义的异常构造逻辑
        // 可以使用`errors`参数来获取验证错误的详细信息
        throw new ValidationException(errors);
      },
    }),
  );
  // Swagger configuration
  const options = new DocumentBuilder()
    .setTitle('Certeasy API')
    .setDescription('API description')
    .setVersion('1.0.0')
    .addBearerAuth()
    .build();

  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('swagger-ui', app, document);
  // 端口和地址
  await app.listen(
    configService.get<number>('app.port', 9527),
    configService.get<string>('app.host', '0.0.0.0'),
    async () => {
      Logger.log('Starting on env: ' + configService.get<string>('app.env'));
      Logger.log(`listening on ${await app.getUrl()}`);
      Logger.log(`swagger running on ${await app.getUrl()}/swagger-ui`);
    },
  );
}
bootstrap();
